#include <stdio.h>
#include <windows.h> 
#include <stdlib.h>
#include <string.h>
#include "storage.h"
#include "storage_system.h"
#include "page.h"
#include <stdint.h>

// 测试结果记录
int total_tests = 0;
int passed_tests = 0;
int current_test_success = 1;

// 测试函数模板
void test_case(const char* name, void (*test_func)()) {
    total_tests++;
    printf("\n=== Test: %s ===\n", name);
    
    // 重置测试成功标志
    current_test_success = 1;
    
    // 运行测试函数
    test_func();
    
    // 检查测试结果
    if (current_test_success) {
        passed_tests++;
        printf("PASS: %s\n", name);
    } else {
        printf("FAIL: %s\n", name);
    }
}

// 断言函数
void assert_true(int condition, const char* message) {
    if (!condition) {
        printf("ASSERTION FAILED: %s\n", message);
        current_test_success = 0;
    }
}

// 测试存储系统初始化和关闭
void test_storage_system_init_shutdown() {
    printf("\nTesting Storage System Initialization and Shutdown...\n");
    
    // 初始化存储系统
    storage_error_t result = init_storage_system("./data");
    assert_true(result == STORAGE_OK, "Failed to initialize storage system");
    
    if (result == STORAGE_OK) {
        // 关闭存储系统
        result = shutdown_storage_system();
        assert_true(result == STORAGE_OK, "Failed to shutdown storage system");
    }
}

// 测试页面分配和释放
void test_page_allocation_free() {
    printf("\nTesting Page Allocation and Free...\n");
    
    // 初始化存储系统
    storage_error_t result = init_storage_system("./data");
    assert_true(result == STORAGE_OK, "Failed to initialize storage system");
    
    if (result == STORAGE_OK) {
        // 分配页面
        page_id_t pid = storage_alloc_page();
        printf("Allocated page ID: %u\n", pid);
        assert_true(pid != 0, "Failed to allocate page");
        
        if (pid != 0) {
            // 为了测试释放功能，先创建一个页面文件
            Page dummy_page;
            memset(dummy_page.data, 0, PAGE_SIZE);
            storage_write_page(pid, &dummy_page);
            
            // 释放页面
            int free_result = storage_free_page(pid);
            assert_true(free_result == 0, "Failed to free page");
        }
        
        // 关闭存储系统
        shutdown_storage_system();
    }
}

// 测试页面读写基本功能
void test_page_read_write_basic() {
    printf("\nTesting Basic Page Read and Write...\n");
    
    // 初始化存储系统
    storage_error_t result = init_storage_system("./data");
    assert_true(result == STORAGE_OK, "Failed to initialize storage system");
    
    if (result == STORAGE_OK) {
        // 分配页面
        page_id_t pid = storage_alloc_page();
        assert_true(pid != 0, "Failed to allocate page");
        
        if (pid != 0) {
            // 创建测试数据
            Page write_page;
            memset(write_page.data, 0, PAGE_SIZE);
            
            // 填充测试数据
            const char* test_string = "This is a storage system test string.";
            strncpy((char*)write_page.data, test_string, strlen(test_string));
            
            // 写入页面
            int write_result = storage_write_page(pid, &write_page);
            assert_true(write_result == 0, "Failed to write page");
            
            // 读取页面
            Page read_page;
            memset(read_page.data, 0, PAGE_SIZE);
            int read_result = storage_read_page(pid, &read_page);
            assert_true(read_result == 0, "Failed to read page");
            
            // 验证数据一致性
            assert_true(memcmp(write_page.data, read_page.data, PAGE_SIZE) == 0, 
                       "Data inconsistency between written and read pages");
            
            printf("Page data verification passed.\n");
            
            // 释放页面
            storage_free_page(pid);
        }
        
        // 关闭存储系统
        shutdown_storage_system();
    }
}

// 测试页面内容正确性（使用随机数据）
void test_page_content_integrity() {
    printf("\nTesting Page Content Integrity...\n");
    
    // 初始化存储系统
    storage_error_t result = init_storage_system("./data");
    assert_true(result == STORAGE_OK, "Failed to initialize storage system");
    
    if (result == STORAGE_OK) {
        // 分配页面
        page_id_t pid = storage_alloc_page();
        assert_true(pid != 0, "Failed to allocate page");
        
        if (pid != 0) {
            // 创建随机测试数据
            Page write_page;
            
            // 填充随机数据
            for (int i = 0; i < PAGE_SIZE; i++) {
                write_page.data[i] = (uint8_t)(i % 256); // 使用可预测的模式进行测试
            }
            
            // 写入页面
            int write_result = storage_write_page(pid, &write_page);
            assert_true(write_result == 0, "Failed to write page");
            
            // 读取页面
            Page read_page;
            int read_result = storage_read_page(pid, &read_page);
            assert_true(read_result == 0, "Failed to read page");
            
            // 验证数据一致性
            int mismatch_count = 0;
            for (int i = 0; i < PAGE_SIZE; i++) {
                if (write_page.data[i] != read_page.data[i]) {
                    mismatch_count++;
                    // 只打印前几个不匹配的位置
                    if (mismatch_count <= 5) {
                        printf("Mismatch at position %d: expected %02x, got %02x\n", 
                               i, write_page.data[i], read_page.data[i]);
                    }
                }
            }
            
            assert_true(mismatch_count == 0, "Data integrity check failed");
            printf("Page content integrity check passed.\n");
            
            // 释放页面
            storage_free_page(pid);
        }
        
        // 关闭存储系统
        shutdown_storage_system();
    }
}

// 测试多页面操作
void test_multiple_pages() {
    printf("\nTesting Multiple Pages Operations...\n");
    
    // 初始化存储系统
    storage_error_t result = init_storage_system("./data");
    assert_true(result == STORAGE_OK, "Failed to initialize storage system");
    
    if (result == STORAGE_OK) {
        const int NUM_PAGES = 5;
        page_id_t pids[NUM_PAGES];
        
        // 分配多个页面
        for (int i = 0; i < NUM_PAGES; i++) {
            pids[i] = storage_alloc_page();
            assert_true(pids[i] != 0, "Failed to allocate multiple pages");
            printf("Allocated page %d with ID: %u\n", i, pids[i]);
        }
        
        // 为每个页面写入唯一数据
        for (int i = 0; i < NUM_PAGES; i++) {
            if (pids[i] != 0) {
                Page page;
                memset(page.data, 0, PAGE_SIZE);
                
                // 写入页面特定标识符
                snprintf((char*)page.data, 20, "PAGE-%d-DATA", i);
                
                // 在页面的不同位置写入索引值，但避开字符串开头位置
                for (int j = 0; j < 100; j++) {
                    int pos = (j * 40) % (PAGE_SIZE - 1);
                    // 确保不会覆盖字符串的前15个字符
                    if (pos < 15) continue;
                    page.data[pos] = (uint8_t)(i + 1);
                }
                
                // 写入页面
                int write_result = storage_write_page(pids[i], &page);
                assert_true(write_result == 0, "Failed to write multiple pages");
            }
        }
        
        // 读取并验证多个页面
        for (int i = 0; i < NUM_PAGES; i++) {
            if (pids[i] != 0) {
                Page page;
                int read_result = storage_read_page(pids[i], &page);
                assert_true(read_result == 0, "Failed to read multiple pages");
                
                // 验证页面标识符
                char expected[20];
                snprintf(expected, 20, "PAGE-%d-DATA", i);
                assert_true(strncmp((char*)page.data, expected, strlen(expected)) == 0, 
                           "Multiple pages data verification failed");
                
                // 释放页面
                storage_free_page(pids[i]);
            }
        }
        
        printf("Multiple pages operation test passed.\n");
        
        // 关闭存储系统
        shutdown_storage_system();
    }
}

// 测试页面初始化和基本操作
void test_page_operations() {
    printf("\nTesting Page Initialization and Basic Operations...\n");
    
    // 初始化存储系统
    storage_error_t result = init_storage_system("./data");
    assert_true(result == STORAGE_OK, "Failed to initialize storage system");
    
    if (result == STORAGE_OK) {
        // 分配页面
        page_id_t pid = storage_alloc_page();
        assert_true(pid != 0, "Failed to allocate page");
        
        if (pid != 0) {
            // 创建并初始化页面
            Page page;
            page_init(&page);
            
            // 插入测试记录
            const char* test_records[] = {
                "First test record",
                "Second test record",
                "Third test record"
            };
            
            int slot_ids[3];
            
            // 插入记录
            for (int i = 0; i < 3; i++) {
                int slot_id;
                int insert_result = page_insert(&page, test_records[i], 
                                              strlen(test_records[i]) + 1, &slot_id);
                assert_true(insert_result == 0, "Failed to insert record into page");
                slot_ids[i] = slot_id;
                printf("Inserted record %d into slot %d\n", i, slot_id);
            }
            
            // 写入页面到存储
            int write_result = storage_write_page(pid, &page);
            assert_true(write_result == 0, "Failed to write page with records");
            
            // 重新读取页面
            Page read_page;
            int read_result = storage_read_page(pid, &read_page);
            assert_true(read_result == 0, "Failed to read page with records");
            
            // 验证记录
            for (int i = 0; i < 3; i++) {
                const void* rec_data;
                uint16_t rec_len;
                int get_result = page_get(&read_page, slot_ids[i], &rec_data, &rec_len);
                assert_true(get_result == 0, "Failed to get record from page");
                assert_true(strcmp((const char*)rec_data, test_records[i]) == 0, 
                           "Record data verification failed");
                printf("Verified record %d: %s\n", i, (const char*)rec_data);
            }
            
            // 删除一条记录并验证
            int delete_result = page_delete(&read_page, slot_ids[1]);
            assert_true(delete_result == 0, "Failed to delete record");
            
            // 验证删除
            const void* rec_data;
            uint16_t rec_len;
            int get_result = page_get(&read_page, slot_ids[1], &rec_data, &rec_len);
            assert_true(get_result == -2, "Record deletion verification failed");
            printf("Record deletion verification passed.\n");
            
            // 释放页面
            storage_free_page(pid);
        }
        
        // 关闭存储系统
        shutdown_storage_system();
    }
}

// 添加清理数据文件的函数
void cleanup_data_files() {
    printf("\n=== Cleaning up test data files ===\n");
    
    // 检查data目录是否存在
    WIN32_FIND_DATAA findFileData;
    HANDLE hFind = FindFirstFileA("./data/page_*.dat", &findFileData);
    
    if (hFind == INVALID_HANDLE_VALUE) {
        printf("No test data files found to clean up.\n");
        return;
    }
    
    // 删除匹配的所有dat文件
    int deleted_files = 0;
    do {
        char file_path[256];
        snprintf(file_path, sizeof(file_path), "./data/%s", findFileData.cFileName);
        
        if (DeleteFileA(file_path)) {
            printf("Deleted file: %s\n", file_path);
            deleted_files++;
        } else {
            printf("Failed to delete file: %s\n", file_path);
        }
    } while (FindNextFileA(hFind, &findFileData) != 0);
    
    FindClose(hFind);
    printf("Total files deleted: %d\n", deleted_files);
}

// 主函数
int main() {
    printf("\n===== Storage System Test Suite =====\n");
    
    // 运行测试用例
    test_case("Storage System Initialization and Shutdown", test_storage_system_init_shutdown);
    test_case("Page Allocation and Free", test_page_allocation_free);
    test_case("Basic Page Read and Write", test_page_read_write_basic);
    test_case("Page Content Integrity", test_page_content_integrity);
    test_case("Multiple Pages Operations", test_multiple_pages);
    test_case("Page Initialization and Basic Operations", test_page_operations);
    
    // 打印测试总结
    printf("\n===== Test Summary =====\n");
    printf("Total tests: %d\n", total_tests);
    printf("Passed tests: %d\n", passed_tests);
    printf("Failed tests: %d\n", total_tests - passed_tests);
    
    if (passed_tests == total_tests) {
        printf("\nAll tests PASSED!\n");
    } else {
        printf("\nSome tests FAILED!\n");
    }
    
    // 调用清理函数删除测试数据文件
    cleanup_data_files();
    
    return (passed_tests == total_tests) ? 0 : 1;
}